home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
loading
/
BldSymX.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-03
|
6KB
|
216 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Xerox PARC
3333 Coyote Hill Rd.
Palo Alto, CA 94304
endcopyright */
/*
* BldSymX.c
*
* Demers, March 9, 1990 9:22:54 am PST
* Aizawa January 5, 1990 2:54:54 pm PST
*/
#include "xr/BasicTypes.h"
#include "xr/IncrementalLoad.h"
#include "xr/BldSymX.h"
/*
* Internal codes -- not client-visible
*/
#define N_IGNORE 0x10
#define N_HEADSTAB 0x12
#define N_PCSTAB 0x14
#define N_BODYSTAB 0x16
#define STRINGSX_OFF 1 /* 0 is not a valid index */
/*
* Kludge -- embedded file names created with identifiable prefix
* (keeps `ld' from discarding file names that start with 'L')
*/
static char *fileNamePrefix = "FILE-"; /* syntax is "FILE-31416-foo.o" */
static char *
NameAsFileName(name)
char *name;
{
char *np, *pp;
int len;
if( name == NIL )
return NIL;
np = name;
pp = fileNamePrefix;
for(;;) {
if( *pp == 0 ) {
name = np;
while( (*np >= '0') && (*np <= '9') ) np++;
return ( (*np == '-') ? (np+1) : name );
}
if( *np++ != *pp++ ) break;
}
if( (len = strlen(name)) < 2 )
return NIL;
if( strcmp((name+len-2), ".o") != 0 )
return NIL;
return name;
}
char *
XR_BldSymX(sxd, allocProc, clientData, staticTextOnly)
XR_SymXData sxd;
char *((*allocProc)(/*void *clientData, XR_SymXData sxd*/));
char *clientData;
bool staticTextOnly;
{
struct nlist *p;
struct nlist *recentStab;
struct nlist *headStab;
int index, bytesLeft;
struct nlistx *pTo;
char *sFrom, *sTo;
struct dbxstabs *stabsTo;
unsigned stabsHiWat;
unsigned char pType;
char *result = NIL;
sxd->sxd_nsymsx = 0;
sxd->sxd_nstringsx = 0;
sxd->sxd_nstabs = 0;
recentStab = NIL;
headStab = NIL;
/*
* Pass through symbol table
* Count stabs groups
* Count symbols we want to keep
*/
for( ((index = 0),(bytesLeft = sxd->sxd_hdr->a_syms),(p = sxd->sxd_syms))
; bytesLeft > 0
; ((index += 1),(p += 1),(bytesLeft -= (sizeof(*p))))
) {
pType = p->n_type;
if( /* DBX STAB */ (pType & N_STAB) != 0 ) {
switch( pType ) {
case N_SO:
if( (headStab == NIL)
|| (headStab->n_value != p->n_value)
|| (p != (recentStab + 1))
) {
/* this is the start of a stab group; */
sxd->sxd_nstabs += 1;
p->n_type = N_HEADSTAB;
headStab = p;
} else {
p->n_type = N_PCSTAB;
}
break;
case N_FUN:
p->n_type = N_PCSTAB;
break;
case N_SLINE:
p->n_type = N_PCSTAB;
break;
default:
p->n_type = N_BODYSTAB;
break;
}
recentStab = p;
} else if( /* sym to keep */ (pType == N_TEXT)
|| ((!staticTextOnly) && (pType & N_EXT)) ) {
sxd->sxd_nsymsx += 1;
if( p->n_un.n_strx != 0 ) {
p->n_un.n_name = sxd->sxd_strings + p->n_un.n_strx;
if( pType == N_TEXT ) /* internal text */ {
char *nameAsFileName = NameAsFileName(p->n_un.n_name);
if( nameAsFileName != NIL ) {
p->n_un.n_name = nameAsFileName;
p->n_type = N_MODULE;
}
}
sxd->sxd_nstringsx += (1 + strlen(p->n_un.n_name));
}
} else /* sym to ignore */ {
p->n_type = N_IGNORE;
}
}
/*
* Call allocProc to allocate new storage
*/
if( sxd->sxd_nstringsx > 0 ) sxd->sxd_nstringsx += STRINGSX_OFF;
result = (*allocProc)(clientData, sxd);
if( result != NIL ) return result;
/*
* Copy the interesting stuff to the newly-allocated storage
*/
pTo = sxd->sxd_symsx;
sTo = sxd->sxd_stringsx + STRINGSX_OFF;
stabsTo = NIL;
for( ((index = 0),(bytesLeft = sxd->sxd_hdr->a_syms),(p = sxd->sxd_syms))
; bytesLeft > 0
; ((index += 1),(p += 1),(bytesLeft -= (sizeof(*p))))
) {
switch( p->n_type ) {
case N_IGNORE:
break;
case N_HEADSTAB:
stabsTo = ( (stabsTo == NIL)
? sxd->sxd_stabs : (stabsTo + 1) );
stabsTo->dbxs_x = index;
stabsTo->dbxs_n = 1;
stabsTo->dbxs_pcLow = stabsTo->dbxs_pcHigh = p->n_value;
break;
case N_PCSTAB:
if( stabsTo == NIL ) /* can't happen? */ {
return "a.out format error: first DBX STAB not SO";
}
if( stabsTo->dbxs_pcHigh < p->n_value )
stabsTo->dbxs_pcHigh = p->n_value;
/* fall thru */
case N_BODYSTAB:
if( stabsTo == NIL ) /* can't happen? */ {
return "a.out format error: first DBX STAB not SO";
}
stabsTo->dbxs_n = (index + 1 - stabsTo->dbxs_x);
break;
default:
bcopy(p, pTo, sizeof(struct nlist));
pTo->nx_x = index;
if( (sFrom = p->n_un.n_name) != NIL ) {
pTo->nx_n.n_un.n_strx = (sTo - sxd->sxd_stringsx);
while( (*sTo++ = *sFrom++) != 0 ) continue;
}
pTo += 1;
break;
}
}
return NIL;
}